﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Web.Security;
using FriendlyURL.Web.Domain.Abstract;
using FriendlyURL.Web.Domain.Models;
using System.Net.Mail;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

namespace FriendlyURL.Web.Domain.Repositories
{
    public class UserRepository : IUserRepository
    {

        private static string CreateSalt()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[32];
            rng.GetBytes(buff);

            return Convert.ToBase64String(buff);
        }

        private static string CreatePasswordHash(string pwd, string salt)
        {
            string saltAndPwd = String.Concat(pwd, salt);
            string hashedPwd =
                    FormsAuthentication.HashPasswordForStoringInConfigFile(
                    saltAndPwd, "sha1");
            return hashedPwd;
        }

        private static string GenerateKey()
        {
            Guid emailKey = Guid.NewGuid();

            return emailKey.ToString();
        }

        public MembershipUser CreateUser(string username, string password, string email)
        {
            using (FriendlyURLEntities db = new FriendlyURLEntities())
            {
                User user = new User();

                user.UserName = username;
                user.LoginID = username;
                user.Email = email;
                user.PasswordSalt = CreateSalt();
                user.Password = CreatePasswordHash(password, user.PasswordSalt);
                user.CreatedDate = DateTime.Now;
                user.IsActivated = false;
                user.IsLockedOut = false;
                user.LastLockedOutDate = DateTime.Now;
                user.LastLoginDate = DateTime.Now;
                user.NewEmailKey = GenerateKey();
                user.RoleID = 1;

                db.AddToUsers(user);
                db.SaveChanges();

                var fromAddress = new MailAddress("yourfromemailaddress@somewhere.com", "Friendly URL");
                var toAddress = new MailAddress(user.Email, user.UserName);
                const string fromPassword = "youremailaddresspassword";
                const string subject = "Activate your account";
                string ActivationLink = "http://localhost:16358/Account/Activate/" +
                                    user.UserName + "/" + user.NewEmailKey;

                var client = new SmtpClient
                    {
                        Host = "youremailhostname",
                        Port = 25,
                        EnableSsl = true,
                        DeliveryMethod = SmtpDeliveryMethod.Network,
                        UseDefaultCredentials = false,
                        Credentials = new System.Net.NetworkCredential(fromAddress.Address, fromPassword)
                    };

                try
                {
                    using (var message = new MailMessage(fromAddress, toAddress)
                                        {
                                            Subject = subject,
                                            Body = ActivationLink
                                        })
                    {
                        ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

                        client.Send(message);
                    }
                }
                catch (Exception ex)
                {
                    //notify user some other way
                }


                return GetUser(username);
            }
        }

        public string GetUserNameByEmail(string email)
        {
            using (FriendlyURLEntities db = new FriendlyURLEntities())
            {
                var result = from u in db.Users where (u.Email.Equals(email)) select u;

                if (result.Count() != 0)
                {
                    var dbuser = result.FirstOrDefault();

                    return dbuser.UserName;
                }
                else
                {
                    return "";
                }
            }
        }

        public MembershipUser GetUser(string username)
        {
            using (FriendlyURLEntities db = new FriendlyURLEntities())
            {
                var result = from u in db.Users where (u.UserName.Equals(username)) select u;

                if (result.Count() != 0)
                {
                    var dbuser = result.FirstOrDefault();

                    string _username = dbuser.UserName;
                    int _providerUserKey = dbuser.UserID;
                    string _email = dbuser.Email;
                    string _passwordQuestion = "";
                    string _comment = dbuser.Comments;
                    bool _isApproved = dbuser.IsActivated;
                    bool _isLockedOut = dbuser.IsLockedOut;
                    DateTime _creationDate = dbuser.CreatedDate;
                    DateTime _lastLoginDate = dbuser.LastLoginDate;
                    DateTime _lastActivityDate = DateTime.Now;
                    DateTime _lastPasswordChangedDate = DateTime.Now;
                    DateTime _lastLockedOutDate = dbuser.LastLockedOutDate;

                    MembershipUser user = new MembershipUser("AccountMembershipProvider",
                                                              _username,
                                                              _providerUserKey,
                                                              _email,
                                                              _passwordQuestion,
                                                              _comment,
                                                              _isApproved,
                                                              _isLockedOut,
                                                              _creationDate,
                                                              _lastLoginDate,
                                                              _lastActivityDate,
                                                              _lastPasswordChangedDate,
                                                              _lastLockedOutDate);

                    return user;
                }
                else
                {
                    return null;
                }
            }
        }

        public bool ValidateUser(string username, string password)
        {
            using (FriendlyURLEntities db = new FriendlyURLEntities())
            {
                
                var result = from u in db.Users where (u.UserName.Equals(username)) select u;

                if (result.Count() != 0)
                {
                    var dbuser = result.First();

                    if (dbuser.Password == CreatePasswordHash(password, dbuser.PasswordSalt) &&
                                                                        dbuser.IsActivated == true)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
        }

        public bool ActivateUser(string username, string key)
        {
            using (FriendlyURLEntities db = new FriendlyURLEntities())
            {
                var result = from u in db.Users where (u.UserName.Equals(username)) select u;

                if (result.Count() != 0)
                {
                    var dbuser = result.First();

                    if (dbuser.NewEmailKey == key)
                    {
                        dbuser.IsActivated = true;
                        dbuser.LastModifiedDate = DateTime.Now;
                        dbuser.NewEmailKey = null;

                        db.SaveChanges();

                        return true;
                    }
                    else
                    {
                        return false;
                    }

                }
                else
                {
                    return false;
                }
            }
        }

        #region UnImplementedMethods
        public User GetUserByLoginID(string loginId)
        {
            throw new NotImplementedException();
        }

        public User GetUserByUserID(int userId)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<User> GetUsers
        {
            get { throw new NotImplementedException(); }
        }

        public bool IsValidUser(string loginId)
        {
            throw new NotImplementedException();
        }

        public bool UserExists(User user)
        {
            throw new NotImplementedException();
        }

        public string[] GetRolesForUser(string loginId)
        {
            throw new NotImplementedException();
        }

        public User AddUser(string domain, string loginId, string fullName, string isAllocator, string isAdmin)
        {
            throw new NotImplementedException();
        }

        public User UpdateUser(int id, string columnName, string value)
        {
            throw new NotImplementedException();
        }

        public bool DeleteUser(int id)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
